<?php
class SwedSampoSebLink extends BankLink {
	
	/**
	* Private key file path
	* @var String
	*/
	protected $privateKey;
	/**
	* Request/Public key file path
	* @var String
	*/
	protected $requestKey;
	/**
	* Reseller identification code
	* @var String
	*/
	protected $resellerId;
	/**
	* Account number
	* @var String
	*/
	protected $resellerAccount;
	/**
	* Account owner
	* @var String
	*/
	protected $resellerName;
	
	/**
	 * Function returns all the input fields required by the bank using BankPayment object.
	 *
	 * @param BankPayment $payment
	 * @return string HTML including input=hidden tags
	 */
	public function sendToBank( $callBackId,  BankPayment $payment ) {
		$rsField = array(
			'VK_SERVICE'    => '1001',
            'VK_VERSION'    => '008',
            'VK_SND_ID'     => $this->resellerId,
            'VK_STAMP'      => $callBackId,
            'VK_AMOUNT'     => $payment->price,
            'VK_CURR'       => $payment->currency,
            'VK_ACC'        => $this->resellerAccount,
            'VK_NAME'       => $this->resellerName,
            'VK_REF'        => $this->referenceNumber($callBackId),
            'VK_MSG'        => $payment->description,
            'VK_RETURN'     => $this->callbackUrl,
            'VK_CANCEL'     => $this->callbackUrl,
			'VK_LANG'		=> "EST",
			'VK_CHARSET'	=> $this->outputEncoding
        	);
        $flKey = openssl_pkey_get_private(file_get_contents($this->privateKey));

		if (!openssl_sign($this->checkSum($rsField, $this->outputEncoding, $this->outputEncoding), $signature, $flKey)) {
			trigger_error ("Unable to generate signature", E_USER_ERROR);
		}

    	$rsField['VK_MAC'] = base64_encode($signature);
    	
		
    	$html = '';
    	foreach ($rsField as $ixField => $fieldValue) {
    		$html .= '<input type="hidden" name="' . $ixField . '" value="' . htmlspecialchars(iconv($this->inputEncoding, $this->outputEncoding, $fieldValue)) . '" />' . "\n";
    	}
    	
    	echo self::getFormBase($this, $html);
		die();
	}
	
	protected function handleCallback() {
		$rsField = array();

	    foreach ((array)$_REQUEST as $ixField => $fieldValue) {
	        if (substr($ixField, 0, 3) == 'VK_') {
	            $rsField[$ixField] = $fieldValue;
	        }
	    }
		
		$flKey = openssl_pkey_get_public(file_get_contents($this->requestKey));
		
		// Invalid signature
		if (!openssl_verify ( $this->checkSum($rsField, $this->outputEncoding, $this->outputEncoding), base64_decode($rsField['VK_MAC']), $flKey)) {
			return array('status' => 4, 'logId' => $rsField['VK_STAMP'], 'bankError'=>'', 'bankErrorStr'=>'');
		
		// payment was cancelled
		} else if ($rsField['VK_SERVICE'] == "1901") {
			return array('status' => 3, 'logId' => $rsField['VK_STAMP'], 'bankError'=>'', 'bankErrorStr'=>'');
		
		// payment successful
		} else if ($rsField['VK_SERVICE'] == "1101") {
			return array('status' => 1, 'logId' => $rsField['VK_STAMP'], 'bankError'=>'', 'bankErrorStr'=>'');
		
		// Other error
		} else {
			return array('status' => 98, 'logId' => $rsField['VK_STAMP'], 'bankError'=>$rsField['VK_SERVICE'], 'bankErrorStr'=>'');
		} 
	}
	
	/**
	* @internal
	*/
	protected function referenceNumber($ixOrder) {
		# reference number calculation using the algorithm provided by Pankade liit
		$rsMultiplier = array (7, 3, 1);
		$ixCurrentMultiplier = 0;
		$sixOrder = (string) $ixOrder;
		for ($i = strlen($sixOrder)-1; $i >= 0; $i--)
		{
			$rsProduct[$i] = substr($sixOrder, $i, 1)*$rsMultiplier[$ixCurrentMultiplier];
			if ($ixCurrentMultiplier == 2)
			{
				$ixCurrentMultiplier = 0;
			}
			else
			{
				$ixCurrentMultiplier++;
			}
		}
		$sumProduct = 0;
		foreach ($rsProduct as $product)
		{
			$sumProduct += $product;
		}
		if ($sumProduct % 10 == 0)
		{
			$ixReference = 0;
		}
		else
		{
			$ixReference = 10 - ($sumProduct % 10);
		}
		return $sixOrder.$ixReference;
	}
	
	/**
	* @internal
	*/
	protected function checkSum($rsField, $nInputEncoding, $outputEncoding) {
		$rsKey = $this->rsKey($rsField['VK_SERVICE']);
		$checkSum = '';
		foreach ($rsKey as $ixField)
		{
			$fieldContents = iconv($nInputEncoding, $outputEncoding, $rsField[$ixField]);
			//$fieldContents = $rsField[$ixField];
			$checkSum .= str_pad(strlen($fieldContents), 3, '0', STR_PAD_LEFT) . $fieldContents;
		}
		return $checkSum;
	}

	/**
	* @internal
	*/
	protected function rsKey($ixService) {
		if ($ixService == 1001)
		{
			return array(
				'VK_SERVICE',
				'VK_VERSION',
				'VK_SND_ID',
				'VK_STAMP',
				'VK_AMOUNT',
				'VK_CURR',
				'VK_ACC',
				'VK_NAME',
				'VK_REF',
				'VK_MSG'
				);
		}
		else if ($ixService == 1101)
		{
			return array(
				'VK_SERVICE',
				'VK_VERSION',
				'VK_SND_ID',
				'VK_REC_ID',
				'VK_STAMP',
				'VK_T_NO',
				'VK_AMOUNT',
				'VK_CURR',
				'VK_REC_ACC',
				'VK_REC_NAME',
				'VK_SND_ACC',
				'VK_SND_NAME',
				'VK_REF',
				'VK_MSG',
				'VK_T_DATE'
				);
		}
		else if ($ixService == 1901)
		{
			return array(
				'VK_SERVICE',
				'VK_VERSION',
				'VK_SND_ID',
				'VK_REC_ID',
				'VK_STAMP',
				'VK_REF',
				'VK_MSG'
				);
		} else {
			return array();
		}
	}
}
?>